#pragma once

#include "defines.h"
#include "critical_lock.h"
#include <queue>
#include <set>
#include "loki/Singleton.h"
#include "loki/AssocVector.h"

class CNetworkHandler;
class CHandlerManager
{
friend class CNetworkHandler;
friend struct Loki::CreateUsingNew< CHandlerManager >;
public:
	struct CHandleGroup : public std::set< _uint32 >
	{
		CCritical	_group_guard;
		_uint32		_network_h;
		CHandleGroup( _uint32 network_h )
			: _network_h( network_h )
		{
		}

		~CHandleGroup()
		{
			CCriticalLock _lock(_group_guard);
		}
	};

private:
	CHandlerManager(void);
	~CHandlerManager(void);
	CHandlerManager( const CHandlerManager& );
	CHandlerManager& operator =( const CHandlerManager& );

public:
	CNetworkHandler* FetchHandle( _uint32 handle );
	void FreeHandle( CNetworkHandler* pHandle );

	size_t HandleCount()const;

	long NewGroup( _uint32 self_handle );
	long EnterGroup( _uint32 group, _uint32 handle );
	long LeaveGroup( _uint32 group, _uint32 handle );
	long RemoveGroup( _uint32 group );

	CHandleGroup*	FetchHandleGroup( _uint32 group );
	void FreeHandleGroup( CHandleGroup* pGroup )const;

protected:
	bool LinkUp( CNetworkHandler* pHandler );
	void LinkDown( CNetworkHandler* pHandler );

private:
	typedef std::queue< _uint32 >	CFreeHandleList;
	typedef std::vector< CNetworkHandler* >	CHandleVec;
	typedef Loki::AssocVector< _uint32, CHandleGroup* >	CGroupMap;
	
	CFreeHandleList	m_free_handle;
	CFreeHandleList m_free_group;


	CHandleVec		m_handle_vector;
	CGroupMap		m_group_map;

	CCritical		m_guard;		
	CCritical		m_group_guard;
};

typedef Loki::SingletonHolder< CHandlerManager, Loki::CreateUsingNew, Loki::DeletableSingleton >	HandlerManager;